package com.northpool.operator.cicd.deploy.runtime;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.http.HttpUtil;
import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.annotation.ParamEnum;
import com.northpool.operator.annotation.ParamEnums;
import com.northpool.operator.cicd.ssh.JschUtils;
import com.northpool.operator.common.algorithm.OperatorTestBuild;
import com.northpool.operator.common.algorithm.TestParamBuilder;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.type.TypeEnum;
import com.northpool.operator.utils.StpOperatorHelper;
import org.w3c.dom.Document;

import javax.xml.xpath.XPathConstants;

@OperatorInfo(
        ref = "JdkDeployOperator",
        name = "Java部署",
        version = "password",
        description = "Java运行环境部署Linux操作系统，支持linux_amd64和linux_arrch64操作系统",
        enums = {
                @ParamEnums(ref = "version", value = {
                        @ParamEnum(ref = "8", name = "8"),
                        @ParamEnum(ref = "11", name = "11"),
                        @ParamEnum(ref = "17", name = "17"),
                        @ParamEnum(ref = "21", name = "21"),
                        @ParamEnum(ref = "23", name = "23")
                }),
                @ParamEnums(ref = "arch", value = {
                        @ParamEnum(ref = "linux_amd64", name = "linux_amd64"),
                        @ParamEnum(ref = "linux_arrch64", name = "linux_arrch64")
                }),
        }
)
public class JdkDeployOperator extends StpOperatorHelper {
    public static String HUB_URL = "http://northpool.work:9000/stp-minio";

    @InputParams({
            @InputParam(ref = "version", name = "Java版本", desc = "指定的Java版本", required = true, type = TypeEnum.ENUM, enumRef = "version", value = "jdk8"),
            @InputParam(ref = "arch", name = "操作系统架构", desc = "操作系统架构, 如: linux_amd64、linux_arrch64", required = false, type = TypeEnum.ENUM, enumRef = "arch", value = "linux_amd64"),
            @InputParam(ref = "sshHost", name = "SSH地址", desc = "SSH远程连接IP地址或域名", required = true),
            @InputParam(ref = "sshPort", name = "SSH端口", desc = "SSH远程连接IP地址或域名", required = false, value = "22", type = TypeEnum.NUMBER),
            @InputParam(ref = "sshUser", name = "SSH用户", desc = "SSH远程连接用户名", required = true),
            @InputParam(ref = "sshPass", name = "SSH密码", desc = "SSH远程连接密码", required = true, type = TypeEnum.SECRET),
            @InputParam(ref = "targetPath", name = "部署路径", desc = "部署到指定的服务器路径", value = "/usr/local/java", type = TypeEnum.STRING),
    })
    public JdkDeployOperator() {
    }

    public static void main(String[] args) {
        OperatorTestBuild.execute(JdkDeployOperator.class, TestParamBuilder.aBuilder()
                .param("version", "21")
                .param("jdkArch", "adm64")
                .param("sshHost", "northpool.work")
                .param("sshPort", "10023")
                .param("sshUser", "root")
                .param("sshPass", "northpool.work@3")
                .param("targetPath", "/usr/local/java")
                .build()
        );
    }

    @Override
    public void execute(ParamTool paramTool) throws Exception {
        String version = paramTool.getStr("version");
        String arch = paramTool.getStr("arch");
        String host = paramTool.getStr("sshHost");
        int port = paramTool.getNumber("sshPort").intValue();
        String user = paramTool.getStr("sshUser");
        String pass = paramTool.getSecret("sshPass");

        TimeInterval timer = DateUtil.timer();
        timer.start();

        String basePath = HUB_URL + "/runtime" + "/" + arch + "/java/" + version + "/";
        String metaPath = basePath + "STP_META.xml";
        String metaBody = HttpUtil.createGet(metaPath).execute().body();
        Document document = XmlUtil.readXML(metaBody);
        String packageName = XmlUtil.getByXPath("//metadata/package", document, XPathConstants.STRING).toString();
        String packagePath = basePath + packageName;

        JschUtils jschUtils = new JschUtils();
        jschUtils.connect(user, pass, host, port);
        String targetPath = paramTool.getStr("targetPath");
        this.log(jschUtils.execCmd("mkdir -p " + targetPath));
        // 下载压缩包
        this.log("下载压缩包: {}", packagePath);
        String downExec = StrUtil.format("cd {} && wget {}", targetPath, packagePath);
        this.log(jschUtils.execCmd(downExec));

        // 解压文件
        this.log("解压文件: {}", packageName);
        // 判断压缩包后缀
        String suffix = FileUtil.getSuffix(packageName);
        String unCompressExec = null;
        if ("tar.gz".equalsIgnoreCase(suffix) || "tgz".equalsIgnoreCase(suffix)) {
            unCompressExec = StrUtil.format("cd {} && tar -zxvf {}", targetPath, packageName);
        } else if ("tar".equalsIgnoreCase(suffix)) {
            unCompressExec = StrUtil.format("cd {} && tar -xvf {}", targetPath, packageName);
        } else {
            this.error("不支持的压缩包格式: {}, 文件名: {}", suffix, packageName);
            this.failedExit();
        }
        this.log(jschUtils.execCmd(unCompressExec));

        // 删除压缩包
        jschUtils.delete(targetPath, packageName);
        this.log("删除压缩包成功: {}", packageName);

        this.log("安装Java版本{},成功!",  version);

        this.log("耗时: {}", DateUtil.formatBetween(timer.interval()));
    }
}
